#include <iostream>
#include "user.pb.h"
#include "mprpcapplication.h"
#include "mprpcprovider.h"

/*
UserService原来是一个本地服务,提供了两个进程内的本地方法,Login和GetFriendLists
使用在rpc服务发布端(rpc服务提供者)
*/
class UserService : public fixbug::UserServiceRpc
{
public:
    bool Login(const std::string& name, const std::string& pwd)
    {
        std::cout << "dong local service: Login" << std::endl;
        std::cout << "name: " << name << "  pwd: " << pwd << std::endl;
        return true;
    }

    bool Register(uint32_t id, const std::string& name, const std::string& pwd)
    {
        std::cout << "doing local service: Register" << std::endl;
        std::cout << "id: " << id << "  name: " << name << "  pwd: " << pwd << std::endl;
        return true;
    }

    /*
    重写基类UserServiceRpc的虚函数实现多态,下面这些方法都是框架直接调用
    以Login()为例子
    caller ==> Login(LoginRequest) ==> muduo ==> callee
    callee ==> Login(LoginReuqest) ==> muduo ==> 交到下面这个重写的Login方法 
    */
    void Login(::google::protobuf::RpcController* controller,
                     const ::fixbug::LoginRequest* request,
                        ::fixbug::LoginResponse* response,
                        ::google::protobuf::Closure* done)
    {
        // 框架给业务上报请求参数LoginReuqest,应用获取相应数据做本地业务
        std::string name = request->name();
        std::string pwd = request->pwd();

        //  本地业务
        bool login_result = Login(name, pwd);

        // 写入响应结果
        fixbug::ResultCode* result = response->mutable_result();
        result->set_errcode(0);
        result->set_errmsg("");
        response->set_success(login_result);

        // 执行回调操作,执行响应对象数据的序列化和网络发送都是由框架来完成
        done->Run();
    }
    void Register(::google::protobuf::RpcController* controller,
                       const ::fixbug::RegisterRequest* request,
                       ::fixbug::RegisterResponse* response,
                       ::google::protobuf::Closure* done)
    {
        uint32_t id = request->id();
        std::string name = request->name();
        std::string pwd = request->pwd();

        bool register_result = Register(id, name, pwd);

        // fixbug::ResultCode* result = response->mutable_result();
        // result->set_errcode(0);
        // result->set_errmsg("");
        response->mutable_result()->set_errcode(0);
        response->mutable_result()->set_errmsg("");
        response->set_success(register_result);

        done->Run();
    }
};

int main(int argc, char** argv)
{
    // 调用框架的初始化操作
    MprpcApplication::Init(argc, argv);

    // provider是一个rpc网络服务对象,把UserService对象发布到rpc节点上
    RpcProvider provider;
    provider.NotifyService(new UserService());

    // // 启动一个rpc服务发布节点,Run以后进程进入阻塞状态,等待远程的rpc调用请求
    provider.Run();

    return 0;
}